package com.shimao.celnet.payment.controller.api;

import com.baiwang.bop.respose.entity.InvoiceQueryResponse;
import com.shimao.celnet.payment.common.exception.BaseException;
import com.shimao.celnet.payment.controller.apinotcheck.CallOut_invOpenOutController;
import com.shimao.celnet.payment.controller.apinotcheck.CallOut_invOpenRetInfoOutController;
import com.shimao.celnet.payment.controller.apinotcheck.CallOut_invPdfOutController;
import com.shimao.celnet.payment.controller.apinotcheck.CallOut_invoiceQueryOutController;
import com.shimao.celnet.payment.model.PInvoiceBlue;
import com.shimao.celnet.payment.model.PInvoiceBlueDetail;
import com.shimao.celnet.payment.model.request.CallIn_OutInvOpenBuleDetailReqIn;
import com.shimao.celnet.payment.model.request.CallIn_newOutInvOpenBuleReqIn;
import com.shimao.celnet.payment.model.response.ErrorInfoEnum;
import com.shimao.celnet.payment.model.response.ResponseJson;
import com.shimao.celnet.payment.service.BInvoiceCompanyService;
import com.shimao.celnet.payment.service.PInvoiceBlueService;
import com.shimao.celnet.payment.service.SCodeNameService;
import com.shimao.celnet.payment.service.apiservice.CallIn_outInvOpenLimitBlueService;
import com.shimao.celnet.payment.util.FinalUtil;
import com.shimao.celnet.payment.util.MyDateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

/**
 * 外部系统 → 支付系统，数据：请求开蓝票信息
 * @Author Jax
 * @Date 17:31 2018/11/22
 **/
@RestController
@RequestMapping(value = "/invoice")
@Api("接口：pay-163(蓝票)-外部立即开票申请<NewOutInvOpenBlueReqIn> 外部系统 → 支付系统，数据：开票详细信息")
public class CallInNewOutInvOpenBlueReqInController {
    protected Logger logger = Logger.getLogger(this.getClass());

    /**
     * 开票申请
     */
    @Autowired
    private PInvoiceBlueService pInvoiceBlueService;

    @Autowired
    private CallOut_invPdfOutController callOut_invPdfOutController;

    /**
     * 参数表
     */
    @Autowired
    private SCodeNameService sCodeNameService;

    /**
     * 开票公司
     */
    @Autowired
    private BInvoiceCompanyService bInvoiceCompanyService;

    @Autowired
    private CallOut_invOpenOutController callOut_invOpenOutController;

    @Autowired
    private CallOut_invoiceQueryOutController callOut_invoiceQueryOutController;

    @Autowired
    private CallOut_invOpenRetInfoOutController callOut_invOpenRetInfoOutController;

    @Autowired
    private CallIn_outInvOpenLimitBlueService callIn_outInvOpenLimitBlueService;

    /**
     * 外部系统开票申请
     *
     * @param requestJson
     * @throws BaseException
     */
    @ApiOperation("获取外部请求开票数据")
    @RequestMapping(value = "/invReqImediaOpenBlue", method = RequestMethod.POST)
    public String OutInvOpenBuleReqIn(@RequestBody @Valid CallIn_newOutInvOpenBuleReqIn requestJson, BindingResult result) throws IOException, ParseException, BaseException {
        ResponseJson retJson = new ResponseJson(ErrorInfoEnum.SUCCESS, "");
        try {
            logger.info("pay-163-外部立即开票申请<NewOutInvOpenBlueReqIn>请求JSON:" + requestJson.toString());
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //通过valid验证
            if (result.hasErrors()) {
                for (FieldError error : result.getFieldErrors()) {
                    logger.debug("缺少必要参数：" + error.getDefaultMessage());
                    retJson = new ResponseJson(ErrorInfoEnum.NOT_PARAMS, error.getDefaultMessage());
                    return retJson.toString();
                }
            }
            //开票类型  00：企业开票  11：个人开票
            String billingType = requestJson.getBillingType();
            String buyerName = requestJson.getBuyerName();
            String buyerBankAccount = requestJson.getBuyerBankAccount();
            String buyerTaxNo = requestJson.getBuyerTaxNo();
            String buyerAddressPhone = requestJson.getBuyerAddressPhone();
            String buyerEmail = requestJson.getBuyerEmail();
            String buyerPhone = requestJson.getBuyerPhone();
            //判断是企业还是个人
            //判断是企业
            JSONObject RetJson = new JSONObject();
            if("00".equals(billingType)) {
                if ("".equals(buyerName) || buyerName == null){
                    RetJson.put("errcode", "1001");
                    RetJson.put("errmsg", "缺少必须参数[buyerName]");
                    RetJson.put("data", null);
                    return RetJson.toString();
                }else if("".equals(buyerBankAccount) || buyerBankAccount == null){
                    RetJson.put("errcode", "1001");
                    RetJson.put("errmsg", "缺少必须参数[buyerBankAccount]");
                    RetJson.put("data", null);
                    return RetJson.toString();
                }else if("".equals(buyerTaxNo) || buyerTaxNo == null){
                    RetJson.put("errcode", "1001");
                    RetJson.put("errmsg", "缺少必须参数[buyerTaxNo]");
                    RetJson.put("data", null);
                    return RetJson.toString();
                }else if("".equals(buyerAddressPhone) || buyerAddressPhone == null){
                    RetJson.put("errcode", "1001");
                    RetJson.put("errmsg", "缺少必须参数[buyerAddressPhone]");
                    RetJson.put("data", null);
                    return RetJson.toString();
                }else if("".equals(buyerEmail) || buyerEmail == null){
                    if("".equals(buyerPhone)  || buyerPhone == null){
                        RetJson.put("errcode", "1001");
                        RetJson.put("errmsg", "[buyerEmail],[buyerPhone]参数必填一个");
                        RetJson.put("data", null);
                        return RetJson.toString();
                    }
                }
            } else if("11".equals(billingType)){//判断是个人
                if ("".equals(buyerName) || buyerName == null){
                    RetJson.put("errcode", "1001");
                    RetJson.put("errmsg", "缺少必须参数[buyerName]");
                    RetJson.put("data", null);
                    return RetJson.toString();
                }else if("".equals(buyerPhone)  || buyerPhone == null){
                    if("".equals(buyerEmail) || buyerEmail == null){
                        RetJson.put("errcode", "1001");
                        RetJson.put("errmsg", "[buyerEmail],[buyerPhone]参数必填一个");
                        RetJson.put("data", null);
                        return RetJson.toString();
                    }
                }
            }
            //获取header中的app_key
            String appKey = request.getHeader(FinalUtil.HEADER_APP_KEY);
            //获取header中的interface_id
            String interfaceId = request.getHeader(FinalUtil.HEADER_INTERFACE_ID);
            logger.info("应用编号：" + appKey);
            logger.info("接口编号：" + interfaceId);
            //定义开蓝票记录对象
            PInvoiceBlue pInvoiceBlue = new PInvoiceBlue();
            //生成开票记录guid
            String receiptGuid = pInvoiceBlueService.getGuid();
            //将开票记录guid返回给请求的外部系统
            retJson.addBody("receiptGuid", receiptGuid);
            pInvoiceBlue.setGuid(receiptGuid);
            //立即开票标识
            pInvoiceBlue.setImmediatelyFlg(requestJson.getImmediatelyFlg());
            //业务类型
            pInvoiceBlue.setBusinessType(requestJson.getBusinessType());
            //小区sfid
            pInvoiceBlue.setEstateSfGuid(requestJson.getEstateId());
            // pInvoiceBlue.setEstatename(requestJson.getEstateName());//小区名称
            //设备类型deviceType
            pInvoiceBlue.setDeviceType(requestJson.getDeviceType());
            //开票限额
            pInvoiceBlue.setLimitAccount(requestJson.getLimitAccount());
            //发票种类
            pInvoiceBlue.setInvoiceTypeCode(requestJson.getInvoiceTypeCode());
            //开票点编码
            pInvoiceBlue.setInvoiceYerminalCode(requestJson.getInvoiceTerminalCode());
            //特殊票种标记
            pInvoiceBlue.setInvoiceSpecialMark(requestJson.getInvoiceSpecialMark());
            //销方单位税号:：根据小区sfguid从开票公司表中取得
            if(bInvoiceCompanyService.getCompanyByEstateSFGuid(requestJson.getEstateId())==null){
                return new ResponseJson(ErrorInfoEnum.ERROR_PARAMS,"世茂无此小区："+requestJson.getEstateId()).toString();
            }
            //取的销方税号
            pInvoiceBlue.setSellerTaxNo(bInvoiceCompanyService.getCompanyByEstateSFGuid(requestJson.getEstateId()).getSellerTaxNo());
            //购方单位名称
            pInvoiceBlue.setBuyerName(buyerName);
            // 购方开户行及账号，专票必填
            pInvoiceBlue.setBuyerBankAccount(buyerBankAccount);
            //  * 购方单位税号
            pInvoiceBlue.setBuyerTaxNo(buyerTaxNo);
            pInvoiceBlue.setBuyerAddressPhone(buyerAddressPhone);
            //购方邮箱
            pInvoiceBlue.setBuyerEmail(buyerEmail);
            //购方电话
            pInvoiceBlue.setBuyerPhone(buyerPhone);

            //开票人
            pInvoiceBlue.setDrawer(requestJson.getDrawer());
            pInvoiceBlue.setChecker(requestJson.getChecker());
            pInvoiceBlue.setPayee(requestJson.getPayee());
            //清单标志
            pInvoiceBlue.setInvoiceListMark(requestJson.getInvoiceListMark());
            //征税方式
            pInvoiceBlue.setTaxationMode(requestJson.getTaxationMode());
            //扣除金额
            pInvoiceBlue.setDeductibleAmount(requestJson.getDeductibleAmount());
            //开票金额合计
            pInvoiceBlue.setInvoiceTotalPriceTax(requestJson.getInvoiceTotalPriceTax());
            //开票开始时间
            pInvoiceBlue.setInvoiceStartTime(MyDateUtil.getReportFileStrDate());
            // 税额合计
            pInvoiceBlue.setInvoiceTotalTax(requestJson.getInvoiceTotalTax());
            //合计金额 不含税
            pInvoiceBlue.setInvoiceTotalPrice(requestJson.getInvoiceTotalPrice());
            pInvoiceBlue.setTaxDiskNo(requestJson.getTaxDiskNo());
            //税控盘-口令
            pInvoiceBlue.setTaxDiskKey(requestJson.getTaxDiskKey());
            //税控盘-密码
            pInvoiceBlue.setTaxDiskPassword(requestJson.getTaxDiskPassword());
            //备注
            pInvoiceBlue.setRemarks(requestJson.getRemarks());
            pInvoiceBlue.setInvoiceType(FinalUtil.INVOICE_BULE);//蓝票
            //作废标记默认为；未作废 0 作废：1
            pInvoiceBlue.setInvlidFlg(FinalUtil.INVLID_FLG_DEFAULT);
            pInvoiceBlue.setInvoicePrintFlg(FinalUtil.INVLID_FLG_PRINT);//打印标记默认为：0未打印  1打印
            pInvoiceBlue.setInvoiceStatus(FinalUtil.INVOICE_STATUS_1);//发票状态；外部请求开票
            pInvoiceBlue.setUserName(requestJson.getUserName());//业主名
            pInvoiceBlue.setHouseName(requestJson.getHouseName());//房源名称
            pInvoiceBlue.setHouseSfId(requestJson.getHouseSfId());//房源sfid
            //serialNo开票流水号；不在接口中传递，支付系统自己生成
            pInvoiceBlue.setSerialNo(sCodeNameService.getInvoiceSellerNumber());
            //外部系统来源
            pInvoiceBlue.setAppKey(appKey);
            //外部系统请求接口
            pInvoiceBlue.setInterfaceId(interfaceId);
            pInvoiceBlue.setRedFlg(FinalUtil.INVOICE_RED_FLG);
            //是否推送标示，0：未推送，1：已推送
            pInvoiceBlue.setIsPush("0");
            //开票明细
            List<CallIn_OutInvOpenBuleDetailReqIn> invoiceReqInDetailsList = requestJson.getInvoiceDetailsList();
            List<PInvoiceBlueDetail> pInvoiceBlueDetailList = new ArrayList<PInvoiceBlueDetail>();
            //对开票记录的明细list遍历
            for (CallIn_OutInvOpenBuleDetailReqIn invoiceDetail : invoiceReqInDetailsList) {
                //定义开票记录明细对象
                PInvoiceBlueDetail pInvoiceBlueDetail = new PInvoiceBlueDetail();
                pInvoiceBlueDetail.setGoodsLineNo(invoiceDetail.getGoodsLineNo());
                ///外部明细id
                pInvoiceBlueDetail.setExsysDetailId(invoiceDetail.getExsysDetailID());
                //发票行性质
                pInvoiceBlueDetail.setGoodsLineNature(invoiceDetail.getGoodsLineNature());
                //开票明细记录 发票行号
                pInvoiceBlueDetail.setGoodsLineNo(invoiceDetail.getGoodsLineNo());
                //开票明细记录 发票行性质
                pInvoiceBlueDetail.setGoodsLineNature(invoiceDetail.getGoodsLineNature());
                pInvoiceBlueDetail.setGoodsCode(invoiceDetail.getGoodsCode());
                ///开票明细记录 自定义商品编码
                pInvoiceBlueDetail.setGoodsExtendCode(invoiceDetail.getGoodsExtendCode());
                //开票明细记录 商品名称
                pInvoiceBlueDetail.setGoodsName(invoiceDetail.getGoodsName());
                //开票明细记录 型号
                pInvoiceBlueDetail.setGoodsSpecification(invoiceDetail.getGoodsSpecification());
                //开票明细记录 单位
                pInvoiceBlueDetail.setGoodsUnit(invoiceDetail.getGoodsUnit());
                pInvoiceBlueDetail.setGoodsQuantity(invoiceDetail.getGoodsQuantity());
                //开票明细记录 单价
                pInvoiceBlueDetail.setGoodsPrice(invoiceDetail.getGoodsPrice());
                //开票明细记录 金额
                pInvoiceBlueDetail.setGoodsTotalPrice(invoiceDetail.getGoodsTotalPrice());
                //开票明细记录 税率
                pInvoiceBlueDetail.setGoodsTaxRate(invoiceDetail.getGoodsTaxRate());
                //含税标志：默认1
                pInvoiceBlueDetail.setPriceTaxMark(FinalUtil.INVLID_PRICE_TAX_MARK);
                //是否使用优惠政策
                pInvoiceBlueDetail.setPreferential(invoiceDetail.getPreferentialMark());
                //缴费时间
                pInvoiceBlueDetail.setPaymentDate(invoiceDetail.getPaymentDate());
                //税额
                pInvoiceBlueDetail.setGoodsTotalTax(invoiceDetail.getGoodsTotalTax());
                //零税率标识：空代表无， 1 出口免税和其他免税优惠政策，2 不征增值税， 3 普通零税率”
                pInvoiceBlueDetail.setFreeTaxMark(invoiceDetail.getFreeTaxMark());
                pInvoiceBlueDetailList.add(pInvoiceBlueDetail);
            }
            // 1、保存蓝票开票记录
            pInvoiceBlueService.save(pInvoiceBlue, pInvoiceBlueDetailList);
            //超过限额进行拆票的开票
            //判断是否需要拆票
            if (Long.valueOf(pInvoiceBlue.getInvoiceTotalPriceTax()) >= Long.valueOf(pInvoiceBlue.getLimitAccount()==null?0L:Long.valueOf(pInvoiceBlue.getLimitAccount())) && pInvoiceBlue.getLimitAccount() != null && pInvoiceBlue.getLimitAccount() != "" && !pInvoiceBlue.getLimitAccount().contains(".")){


                JSONObject RetJsonObject  = callIn_outInvOpenLimitBlueService.outInvOpenLimitBuleReqInService(pInvoiceBlue);
                retJson.addBody("data",RetJsonObject);
                return retJson.toString();
            }
            // 2、调用百望开票接口开票
            //调用立即开票接口
            PInvoiceBlue pInvoiceBlueRet = callOut_invOpenOutController.invoiceBlueFromImmRequest(pInvoiceBlue);
            if (pInvoiceBlueRet != null) {
                //  3、调用百望开票结果查询接口，查询开票结果
                InvoiceQueryResponse response = callOut_invoiceQueryOutController.invoiceBlueQueryOut(pInvoiceBlueRet);
                //返回结果
                if(response == null){
                    return new ResponseJson(ErrorInfoEnum.FAIL_QUERY, "发票"+pInvoiceBlueRet.getGuid()).toString();
                }
                //  4、开电子发票时，调研百望电子发票查询接口，获取电子发票URL
                String strUrl = null;
                if(FinalUtil.INVOICE_TYPE_CODE_026.equals(pInvoiceBlue.getInvoiceTypeCode())){
                    strUrl =  callOut_invPdfOutController.invPdfOut(pInvoiceBlue);
                }
                //生成返回结果集
                JSONObject RetJsonObject = callOut_invOpenRetInfoOutController.invOpenRetBlueInfoOut(response,pInvoiceBlue,strUrl);
                RetJson.put("errcode", "0000");
                RetJson.put("errmsg", "处理成功");
                RetJson.put("data", RetJsonObject);
                return RetJson.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
            retJson = new ResponseJson(ErrorInfoEnum.FAIL_OPEN, e.getMessage());
        }
        return retJson.toString();
    }
}
